/*
*  Copyright 2019-2023 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.yangxu.hospital.system.modules.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.yangxu.hospital.common.exception.BadRequestException;
import com.yangxu.hospital.common.utils.FileUtil;
import com.yangxu.hospital.common.utils.PageResult;
import com.yangxu.hospital.common.utils.PageUtil;
import com.yangxu.hospital.common.utils.StringUtils;
import com.yangxu.hospital.system.modules.system.domain.Menu;
import com.yangxu.hospital.system.modules.system.domain.SysDepartment;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yangxu.hospital.system.modules.system.service.SysDepartmentService;
import com.yangxu.hospital.system.modules.system.domain.vo.SysDepartmentQueryCriteria;
import com.yangxu.hospital.system.modules.system.mapper.SysDepartmentMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @description 服务实现
* @author 杨旭
* @date 2024-11-25
**/
@Service
@RequiredArgsConstructor
public class SysDepartmentServiceImpl extends ServiceImpl<SysDepartmentMapper, SysDepartment> implements SysDepartmentService {

    private final SysDepartmentMapper sysDepartmentMapper;

//    @Override
//    public PageResult<SysDepartment> queryAll(SysDepartmentQueryCriteria criteria, Page<Object> page){
//        return PageUtil.toPage(sysDepartmentMapper.findAll(criteria, page));
//    }

    @Override
    public List<SysDepartment> queryAll(SysDepartmentQueryCriteria criteria, Boolean isQuery) throws Exception {
        if(Boolean.TRUE.equals(isQuery)){
            criteria.setPidIsNull(true);
            List<Field> fields = StringUtils.getAllFields(criteria.getClass(), new ArrayList<>());
            for (Field field : fields) {
                //设置对象的访问权限，保证对private的属性的访问
                field.setAccessible(true);
                Object val = field.get(criteria);
                if("pidIsNull".equals(field.getName())){
                    continue;
                }
                // 如果有查询条件，则不指定pidIsNull
                if (ObjectUtil.isNotNull(val)) {
                    criteria.setPidIsNull(null);
                    break;
                }
            }
        }
        return sysDepartmentMapper.findAll(criteria);
    }

    @Override
    public List<SysDepartment> queryAll(SysDepartmentQueryCriteria criteria){
        return sysDepartmentMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(SysDepartment resources) {

        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(new LambdaQueryWrapper<SysDepartment>()
                .eq(SysDepartment::getName, resources.getName()));
        if (sysDepartments.size() > 0) {
            throw new BadRequestException("该诊室已存在");
        }
        if (Long.valueOf(0L).equals(resources.getParentId())) {
            resources.setParentId(null);
        }
        save(resources);
        resources.setSubCount(0);
        updateSubCnt(resources.getParentId());
    }
    private void updateSubCnt(Long department_id){
        if(department_id != null){
            int count = sysDepartmentMapper.countByPid(department_id);
            sysDepartmentMapper.updateSubCntById(count, department_id);
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysDepartment resources) {
        SysDepartment sysDepartment = getById(resources.getDepartmentId());
        sysDepartment.copy(resources);
        saveOrUpdate(sysDepartment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        removeBatchByIds(ids);
    }

    @Override
    public void download(List<SysDepartment> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (SysDepartment sysDepartment : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("科室名称", sysDepartment.getName());
            map.put("描述", sysDepartment.getDescription());
            map.put("创建时间", sysDepartment.getCreateTime());
            map.put("更新时间", sysDepartment.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<SysDepartment> getDepartment(Long pid) {
        List<SysDepartment> departments;
        if (pid != null & !pid.equals(0L)) {
            departments = sysDepartmentMapper.findByPidOrderByMenuSort(pid);
        } else {
            departments = sysDepartmentMapper.findByPidIsNullOrderByMenuSort();
        }
        return departments;
    }

    @Override
    public SysDepartment findById(Long id) {
        return getById(id);
    }

    @Override
    public List<SysDepartment> getSuperior(SysDepartment sysDepartment, List<SysDepartment> sysDepartments) {
        if (sysDepartment.getParentId() == null){
            sysDepartments.addAll(sysDepartmentMapper.findByPidIsNullOrderByMenuSort());
            return sysDepartments;
        }
        sysDepartments.addAll(sysDepartmentMapper.findByPidOrderByMenuSort(sysDepartment.getParentId()));
        return Collections.emptyList();
    }

    @Override
    public List<SysDepartment> buildTree(List<SysDepartment> sysDepartments) {
        List<SysDepartment> trees = new ArrayList<>();
        Set<Long> ids = new HashSet<>();
        for (SysDepartment sysDepartment1 : sysDepartments) {
            if (sysDepartment1.getParentId() == null) {
                trees.add(sysDepartment1);
            }
            for (SysDepartment it : sysDepartments) {
                if (sysDepartment1.getDepartmentId().equals(it.getParentId())) {
                    if (sysDepartment1.getChildren() == null) {
                        sysDepartment1.setChildren(new ArrayList<>());
                    }
                    sysDepartment1.getChildren().add(it);
                    ids.add(it.getDepartmentId());
                }
            }
        }
        return Collections.emptyList();
    }

    @Override
    public Set<SysDepartment> getchildDepartment(List<SysDepartment> departments, Set<SysDepartment> sysDepartmentHashSet) {
        for (SysDepartment sysDepartment : departments){
            sysDepartmentHashSet.add(sysDepartment);
            List<SysDepartment> byPidOrderByMenuSort = sysDepartmentMapper.findByPidOrderByMenuSort(sysDepartment.getDepartmentId());
            if (byPidOrderByMenuSort != null && byPidOrderByMenuSort.size() != 0){
                getchildDepartment(byPidOrderByMenuSort,sysDepartmentHashSet);
            }
        }
        return sysDepartmentHashSet;
    }

    @Override
    public void delete(Set<SysDepartment> sysDepartmentSet) {
        for (SysDepartment sysDepartment : sysDepartmentSet) {
            sysDepartmentMapper.deleteById(sysDepartment.getDepartmentId());
            updateSubCnt(sysDepartment.getParentId());
        }
    }
}